package com.cqan.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.cqan.common.Constant;

/**
 * 生成一次性或N次有效性验证码
 * 
 * @author slaton
 * 
 */
public class TokenCachePool{

	/**
	 * 验证码默认有效期10分钟
	 */
	private long time = 60*10;

	/**
	 * 有效次数，默认有效1次
	 */
	private int valid = 1;

	/**
	 * 初始容器大小为50
	 */
	private static int initsize = 50;

	/**
	 * 对象池，初始容量为 20
	 */
	private static final Map<String,TokenEntity> pool = new HashMap<String,TokenEntity>(initsize);

	private static TokenCachePool vcp = null;

	private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

	private TokenCachePool() {
		scheduler.scheduleAtFixedRate(new ClearTask(), 1, 30, TimeUnit.SECONDS);
	}

	public static TokenCachePool getInstance() {
		if (vcp == null) {
			return new TokenCachePool();
		}
		return vcp;
	}

	public String generate() {
		String token = Constant.random();
		TokenEntity te = new TokenEntity(token, valid);
		pool.put(token,te);
		return token;
	}

	public boolean Verify(String token){
		TokenEntity te = pool.get(token);
		if (te!=null) {
			--te.valid;
			if (te.valid<=0) {
				pool.remove(token);
			}
			return true;
		}
		return false;
	}


	@SuppressWarnings("unused")
	private class TokenEntity {

		private String token;

		private long ts;

		private int valid;

		public TokenEntity(String token, long ts, int valid) {
			this.token = token;
			this.ts = ts;
			this.valid = valid;
		}

		public TokenEntity(String token, int valid) {
			this.token = token;
			this.ts = System.currentTimeMillis();
			this.valid = valid;
		}

		@Override
		public int hashCode() {
			
			return super.hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			TokenEntity vce = (TokenEntity)obj;
			if (vce.token.equals(this.token)) {
				return true;
			}
			return false;
		}
		
	}

	/**
	 * 定时清理过期的TOKEN
	 * @author slaton
	 *
	 */
	class ClearTask implements Runnable {

		public void run() {
			Set<Entry<String, TokenEntity>> set = pool.entrySet();
			Iterator<Entry<String, TokenEntity>> it = set.iterator();
			while (it.hasNext()) {
				Entry<String, TokenEntity> entity = (Entry<String, TokenEntity>) it.next();
				if (entity!=null) {
					TokenEntity  vc = entity.getValue();
					long ct = System.currentTimeMillis() - time * 1000;
					if (vc != null && vc.ts <= ct) {
						it.remove();
					}
				}
			}
		}
	}

}
